package com.open.basic;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.open.basic.enums.StatusEnum;
import com.open.basic.exception.SystemException;
import lombok.Getter;
import lombok.Setter;

import java.io.Serial;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * @author: system
 * @Date: 2024/4/11 23:50
 * @Version: V1.0
 * @description: desc:根对象信息
 */

@Setter
@Getter
public class RootInfo implements Serializable {

    @Serial
    private static final long serialVersionUID = 8184803809060382991L;
    private volatile String[] fieldArray;

    /**
     * 主键ID
     */
    private String id;
    /**
     * 对象名称
     */
    private String name;
    /**
     * 对象状态
     * @see com.open.basic.enums.StatusEnum
     */
    private int status;
    /**
     * 对象描述
     */
    private String desc;

    /**
     * 域ID
     */
    private String tenantId = "default";
    /**
     * 创建时间 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime createTime;
    /**
     * 更新时间 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime updateTime;

    /**
     * get fieldArray, this field is not final and not static
     *
     * @return
     */
    public String[] getFieldArray() {
        if (fieldArray == null) {
            synchronized (this) {
                if (fieldArray == null) {
                    Class<? extends RootInfo> clazz = this.getClass();
                    Field[] declaredFields = clazz.getDeclaredFields();
                    Arrays.stream(declaredFields).map(item -> {
                        int modifiers = item.getModifiers();
                        if (Modifier.isStatic(modifiers) || Modifier.isFinal(modifiers)) {
                            return null;
                        }
                        return item.getName();
                    }).filter(Objects::nonNull).collect(Collectors.toList()).toArray(new String[declaredFields.length]);
                }
            }
        }
        return fieldArray;
    }

    /**
     * 判断是否存在该字段
     *
     * @param fieldName
     * @return
     */
    public boolean existField(String fieldName) {
        String[] fieldArray = getFieldArray();
        for (String field : fieldArray) {
            if (Objects.equals(fieldName, field)) {
                return true;
            }
        }
        return false;
    }


    private void setStatus(int status) {
        if (!StatusEnum.exist(status)) {
            throw new SystemException("status is not exist");
        }
        this.status = status;
    }
}
